package org.example.myleet.rosalind.utils;

import java.util.concurrent.atomic.AtomicInteger;

public class NewickTreeUtil {

    private static final AtomicInteger id = new AtomicInteger(0);

    public static int getNextId() {
        return id.addAndGet(1);
    }

    public static NewickTreeNode parse(NewickTreeNode parent, String serialized) {
        if (serialized.endsWith(";")) {
            return parse(parent, serialized.substring(0, serialized.length() - 1));
        }
        if (serialized.startsWith("(")) {
            //有括号包裹的情况，按子节点方式解析
            int i = serialized.length() - 1;
            for (; i >= 0; --i) {
                if (serialized.charAt(i) == ')') {
                    break;
                }
            }
            //截取括号右侧的节点信息解析出当前节点
            String nodeInfo = serialized.substring(i + 1);
            int weight = 0;
            String value;
            if (nodeInfo.contains(":")) {
                String[] parts = nodeInfo.split(":");
                value = parts[0];
                weight = Integer.parseInt(parts[1]);
            } else {
                value = nodeInfo;
            }
            NewickTreeNode node = new NewickTreeNode(getNextId(), weight, value, parent);
            //然后分别截取每个子节点的信息进行解析
            StringBuilder childSerialized = new StringBuilder();
            for (int j = 1; j < i; ++j) {
                char c = serialized.charAt(j);
                if (c == ',') {
                    //找到一个完整的子节点信息，递归解析
                    NewickTreeNode child = parse(node, childSerialized.toString());
                    node.getChildren().add(child);
                    childSerialized = new StringBuilder();
                } else if (c == '(') {
                    //找到一个包含了孙子节点的子节点信息，在保证括号一一对应的情况下截取完整的子节点信息
                    childSerialized.append(c);
                    ++j;
                    int bracketLevel = 1;
                    while (bracketLevel > 0) {
                        c = serialized.charAt(j);
                        if (c == '(') {
                            ++bracketLevel;
                        } else if (c == ')') {
                            --bracketLevel;
                        }
                        childSerialized.append(c);
                        ++j;
                    }
                    --j;
                } else {
                    childSerialized.append(c);
                }
            }
            if (childSerialized.length() > 0) {
                //如果childSerialized还有剩余字符说明还有一个子节点信息，解析之
                NewickTreeNode child = parse(node, childSerialized.toString());
                node.getChildren().add(child);
            }
            return node;
        }
        //如果没有括号包裹的情况
        int weight = 0;
        String value;
        if (serialized.contains(":")) {
            String[] parts = serialized.split(":");
            value = parts[0];
            weight = Integer.parseInt(parts[1]);
        } else {
            value = serialized;
        }
        return new NewickTreeNode(getNextId(), weight, value, parent);
    }

    public static void serialize(NewickTreeNode parent, StringBuilder res) {
        if (parent.getChildren().size() > 0) {
            res.append(parent.getValue()).append('(');
            for (NewickTreeNode child : parent.getChildren()) {
                serialize(child, res);
                res.append(',');
            }
            res.deleteCharAt(res.length() - 1);
            res.append(')');
        } else {
            res.append(parent.getValue());
        }
    }
}
